﻿using System;
using ActivateYourGlutes.Data;
using Microsoft.Practices.ServiceLocation;

namespace ActivateYourGlutes.Services.Model
{
    public class MeasurementType
    {
        public int MeasurementTypeId { get; set; }

        public string Description { get; set; }

        public string Type { get; set; }

        public bool IsAbsolute { get { return Type == Data.Model.MeasurementType.Absolute; } }

        public bool IsPercentage { get { return Type == Data.Model.MeasurementType.Percentage; } }

        public bool IsWeight { get { return Type == Data.Model.MeasurementType.Weight; } }

        public bool IsLength { get { return Type == Data.Model.MeasurementType.Length; } }

        public bool IsSystem { get { return UserDefinedTypeOwner == null; }}

        public Account UserDefinedTypeOwner { get; set; }

        public int DisplayOrder { get; set; }

        public string Unit
        {
            get
            {
                string unit = "";
                if (IsPercentage)
                    unit = "%";
                else if (IsWeight)
                {
                    var localisationProvider = ServiceLocator.Current.GetInstance<ILocalisationProvider>();
                    unit = localisationProvider.UnitOfWeight.Unit;
                }
                else if (IsLength)
                {
                    var localisationProvider = ServiceLocator.Current.GetInstance<ILocalisationProvider>();
                    unit = localisationProvider.UnitOfLength.Unit;
                }
                return unit;
            }
        }

        public double LocaliseValue(double value)
        {
            if (IsAbsolute || IsPercentage)
                return value;
            if (IsWeight)
            {
                var localisationProvider = ServiceLocator.Current.GetInstance<ILocalisationProvider>();
                var weightMultiplier = localisationProvider.UnitOfWeight.ToKgMultiplier;
                return Math.Round(value / weightMultiplier, 1);
            }
            if (IsLength)
            {
                var localisationProvider = ServiceLocator.Current.GetInstance<ILocalisationProvider>();
                var lengthMultiplier = localisationProvider.UnitOfLength.ToMetersMultiplier;
                return Math.Round(value / lengthMultiplier, 1);
            }
            throw new ModelException("A unit of measurement is in use that does not have associated localisation logic.");
        }

        public double DelocaliseValue(double value)
        {
            if (IsAbsolute || IsPercentage)
                return value;
            if (IsWeight)
            {
                var localisationProvider = ServiceLocator.Current.GetInstance<ILocalisationProvider>();
                var weightMultiplier = localisationProvider.UnitOfWeight.ToKgMultiplier;
                return value * weightMultiplier;
            }
            if (IsLength)
            {
                var localisationProvider = ServiceLocator.Current.GetInstance<ILocalisationProvider>();
                var lengthMultiplier = localisationProvider.UnitOfLength.ToMetersMultiplier;
                return value * lengthMultiplier;
            }
            throw new ModelException("A unit of measurement is in use that does not have associated localisation logic.");
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != typeof (MeasurementType)) return false;
            return Equals((MeasurementType) obj);
        }

        public bool Equals(MeasurementType other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return other.MeasurementTypeId == MeasurementTypeId;
        }

        public override int GetHashCode()
        {
            return MeasurementTypeId;
        }
    }
}